/*
 * CGameBase.h
 *
 *  Created on: Sep 1, 2011
 *      Author: welcome
 */

#ifndef CGAMEBASE_H_
#define CGAMEBASE_H_

#include <ac3dui/ac.h>
#include <KD/EXT_multitouch.h>
#include <KD/kd.h>
#include <EGL/egl.h>
#include <GLES/gl.h>
#include <CAudioManager.h>
#include <CLight.h>
#include <CCamera.h>
#include <CFog.h>
#include <gg2d/gg2d.h>
#include <rdesktop.h>

#define STRNCPY(dst,src,n)	{ strncpy(dst,src,n-1); dst[n-1] = 0; }

namespace GGEngine {

struct GameSpec {
	enum value {
		FPS = 60
	};
};

struct Touch {
	KDint index;
	KDfloat32 x;
	KDfloat32 y;
	KDust timestamp;
};

class CGameBase: public acObject {

protected:
	/*
	 * Gonna implemented by child class
	 */
	virtual void OnEvent(const KDEvent *event) {
		kdDefaultEvent(event);
	}

	virtual void OnWindowFocus(int state) {
		if (state == 0) {
			PauseBgMusic();
		} else {
			ResumeBgMusic();
		}
	}

	virtual void OnPause() {
		PauseBgMusic();
	}

	virtual void OnResume() {
		ResumeGraphics();
		ResumeBgMusic();
	}

	virtual void OnPointerMove(int x, int y, int buttonstate) {
		acUIManager * pUIManager = acUIManager::GetInstance();
		if (buttonstate) {
			pUIManager->TouchMove(x, y);
		}
	}

	virtual void OnPointerSelect(int x, int y, int buttonstate) {
		acUIManager * pUIManager = acUIManager::GetInstance();
		if (buttonstate == 0) // up
		{
			pUIManager->TouchUp(x, y);
		} else if (buttonstate == 1) // down
		{
			pUIManager->TouchDown(x, y);
		}
	}

	virtual void OnKey(int kdKeyCode, int state) {

	}

	virtual void OnTouchBegin(bool first, GGEngine::Touch *touch) {
	}

	virtual void OnTouchMove(GGEngine::Touch *touch) {
	}

	virtual void OnTouchEnd(bool last, GGEngine::Touch *touch) {
	}

	virtual void OnUpdate(int deltaTime);

public:

	KDint connect(char* server, char* userName, char* passWord);

	KDint disconnect();

	virtual ~CGameBase();

	static CGameBase* GetInstance();

	void MainLoop();

	KDint SwapBuffers(void);

	acUIManager* GetUIManager();

	void GetWindowSize(int* iWidth, int* iHeight);

	void AddPage(acPage* page);

	int GetDeltaTime();

	void SetMultitouchEnable(bool enabled);

	static KDtime GetFrametime();

	/*
	 * Music
	 */
	int PlayBgMusic(const char* fileName);

	int PauseBgMusic();

	int ResumeBgMusic();

	int SkiptimeBgMusic();

	/*
	 * Light source
	 */
	void setLight(CLight *m_light);

	CLight* getLight();
	/*
	 * Camera
	 */
	void setCameraCount(int cameraCount);

	int getCameraCount();

	CCamera *getCamera(int cameraIndex);

	void setActiveCamera(int cameraIndex);

	CCamera *getActiveCamera();
	/*
	 * Fog
	 */

	void setFog(CFog *m_fog);

	bool isQuitting;

	bool isPaused;

	bool isFocused;

	/*
	 * Event callback
	 */
	void EventCallback(const KDEvent *e);

private:

	CGameBase();

	KDint Initialize();

	void Release();

	void handle(const KDEvent *e);

	KDint FindTouch(const KDEvent *event);

	void AddTouch(const KDEvent *event);

	void RemoveTouch(const KDEvent *event);

	void ModifyTouch(const KDEvent *event);
	/*
	 * Graphic related methods
	 */
	KDint InitializeGraphics(void);

	void ReleaseGraphics(void);

	KDint ResumeGraphics(void);

	KDint InitializeEGLConfig();

	KDint InitializeWindow();

	KDint InitializeGLES();

	EGLBoolean RecreateEGLContext(void);

	/*
	 * Private update method
	 */

	KDint Update(int deltaTime);

	/*
	 * Private variables
	 */
	static CGameBase* appInstance;

	KDint32 screenWidth;
	KDint32 screenHeight;

	KDWindow * window;
	EGLDisplay eglDisplay;
	EGLSurface eglWindowSurface;
	EGLContext eglContextOpenGLES;
	EGLConfig eglConfig;
	acUIManager* pUIManager;

	static int bgmusic;

	static KDtime frameTime;

	KDtime lastTime;
	/*
	 * Light source
	 */
	CLight* m_light;

	/*
	 * Multiple camera support
	 */
	int m_cameraCount;

	int m_cameraIndex;

	CCamera *m_cameras;

	std::vector<Touch> touches;
	/*
	 * Fog
	 */
	CFog* m_fog;

	RD_BOOL deactivated;

	uint32 ext_disc_reason;
};

} /* namespace GGEngine */
#endif /* CGAMEBASE_H_ */
